package cn.xttc.edu.controller;

import cn.xttc.edu.entity.*;
import cn.xttc.edu.entity.sms.SendResponse;
import cn.xttc.edu.entity.sms.VerifyResponse;
import cn.xttc.edu.entity.template.OrderStatusTemplateData;
import cn.xttc.edu.entity.template.WxTemplate;
import cn.xttc.edu.entity.template.WxTemplatesConst;
import cn.xttc.edu.entity.vo.OrderVo;
import cn.xttc.edu.service.CarService;
import cn.xttc.edu.service.CustomerService;
import cn.xttc.edu.service.DriverService;
import cn.xttc.edu.service.OrderService;
import cn.xttc.edu.util.HttpUtils;
import cn.xttc.edu.util.MyUtil;
import cn.xttc.edu.util.sms.SendSMSUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.soecode.wxtools.api.IService;
import com.soecode.wxtools.api.WxService;
import com.soecode.wxtools.exception.WxErrorException;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 处理微信公众号中司机的相关请求的controller
 * @author yl
 */
@RestController
@RequestMapping("/wx")
public class WxDriverController {
    private String filename = "";
    private String licencePicFilename = "";
    /**
     * 订单更新模板id
     */
    private static final String TEMPLATEID = "Aud0QVwMzyLAxqD4Uh5O1wYBptasKyhC2p9nSPFpdzI";
    private String requestId;

    @Autowired
    private DriverService driverService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private CarService carService;
    @Autowired
    private CustomerService customerService;

    /**
     * 根据openid查询司机
     *
     * @param openid openid
     * @return 包装对象
     */
    @GetMapping("/driver/{openid}")
    public ReturnMsg getDriverByOpenid(@PathVariable("openid") String openid) {
        Driver driver = driverService.getOne(new QueryWrapper<Driver>().eq("open_id", openid));
        if (driver == null) {
            return ReturnMsg.fail("您还未注册");
        } else {
            return ReturnMsg.success(driver);
        }
    }

    /**
     * 获取所有未接单的订单
     *
     * @return 包装对象
     */
    @GetMapping("/orders")
    public ReturnMsg getAllWaitingOrders() {
        List<OrderVo> list = orderService.getAllWaitingOrders();
        return ReturnMsg.success(list);
    }

    /**
     * 根据openid和订单状态查询订单
     *
     * @param openid 司机openid
     * @param status 订单状态
     * @return 包装对象
     */
    @GetMapping("/driver/order")
    public ReturnMsg getOrdersByDriverIdAndStatus(@RequestParam("openid") String openid,
                                             @RequestParam("status") Integer status) {
        Driver driver = driverService.getOne(new QueryWrapper<Driver>().eq("open_id", openid));
        if (driver != null) {
            List<OrderVo> list = orderService.getOrdersByDIdAndStatus(driver.getId(), status);
            return ReturnMsg.success(list);
        }
        return ReturnMsg.fail("");
    }

    /**
     * 回显人物照片
     *
     * @param pic     人物照片
     * @param request request
     * @return json字符串
     */
    @PostMapping("/driver_pic")
    public Object handleDriverPic(MultipartFile pic, HttpServletRequest request) {
        //生成要保存的文件名
        filename = MyUtil.getUUIDFileName() + MyUtil.getFileType(Objects.requireNonNull(pic.getOriginalFilename()));
        //得到项目中图片存储的路径
        String path = "D:\\workplace\\Java_workplace\\JiAnTransport\\src\\main\\webapp\\static\\driver_pic";
        String serverPath = request.getServletContext().getRealPath("/static/driver_pic");

        //转存
        try {
            FileUtils.copyInputStreamToFile(pic.getInputStream(), new File(path + File.separator + filename));
            FileUtils.copyInputStreamToFile(pic.getInputStream(), new File(serverPath + File.separator + filename));
        } catch (IOException e) {
            e.printStackTrace();
        }

        //返回客户端JSON对象,封装图片的路径,为了在页面实现立即回显
        JSONObject object = new JSONObject();
        object.put("imgurl", filename);
        return object.toString();
    }

    /**
     * 回显驾驶证照片
     *
     * @param licencePic 驾驶证照片
     * @param request    request
     * @return json字符串
     */
    @PostMapping("/licence_pic")
    public Object handleLicencePic(MultipartFile licencePic, HttpServletRequest request) {
        //生成要保存的文件名
        licencePicFilename = MyUtil.getUUIDFileName() + MyUtil.getFileType(Objects.requireNonNull(licencePic.getOriginalFilename()));
        //得到项目中图片存储的路径
        String path = "D:\\workplace\\Java_workplace\\JiAnTransport\\src\\main\\webapp\\static\\licence_pic";
        String serverPath = request.getServletContext().getRealPath("/static/licence_pic");

        //转存
        try {
            FileUtils.copyInputStreamToFile(licencePic.getInputStream(), new File(path + File.separator + licencePicFilename));
            FileUtils.copyInputStreamToFile(licencePic.getInputStream(), new File(serverPath + File.separator + licencePicFilename));
        } catch (IOException e) {
            e.printStackTrace();
        }

        //返回客户端JSON对象,封装图片的路径,为了在页面实现立即回显
        JSONObject object = new JSONObject();
        object.put("imgurl", licencePicFilename);
        return object.toString();
    }

    /**
     * 保存司机
     * @param driver 司机信息
     * @param code 验证码
     * @return 包装对象
     */
    @PostMapping("/driver")
    public ReturnMsg save(Driver driver, @RequestParam("code") String code ) {
        //验证短信验证码
        VerifyResponse verifyResponse = SendSMSUtils.verifyOtp(requestId, code);
        //根据相应结果判断是否验证成功
        if (verifyResponse.getData().isMatch()) {
            //验证成功，如果openid为空，说明是模拟司机，给一个随机的openid
            if ("".equals(driver.getOpenId())) {
                String openid = UUID.randomUUID().toString().replace("-", "");
                driver.setOpenId(openid);
            }
            //设置人物图片名称和驾驶证图片名称
            driver.setPic(filename).setLicencePic(licencePicFilename);
            driverService.save(driver);
            return ReturnMsg.success("申请提交成功，请耐心等待审核通过");
        } else {
            //验证失败
            if (verifyResponse.getData().getReasonType() == 2) {
                return ReturnMsg.fail("验证码错误");
            } else {
                return ReturnMsg.fail("验证码已过期或不存在");
            }
        }


    }

    /**
     * 发送注册短信验证码
     * @param phone 手机号
     * @return 包装对象
     */
    @PostMapping("/sendCode")
    public ReturnMsg sendCode(@RequestParam("phone") String phone) {
        //发送短信验证码
        SendResponse sendResponse = SendSMSUtils.sendOtp(phone);
        //将requestId存储保存到全局变量
        requestId = sendResponse.getData().getRequestId();
        return ReturnMsg.success("验证码发送成功");
    }

    /**
     * 修改司机申请
     *
     * @param driver 司机信息
     * @param code 验证码
     * @return 包装对象
     */
    @PutMapping("/driver")
    public ReturnMsg editDriver(Driver driver,
                                @RequestParam("code") String code
                                ) {
        //校验验证码
        VerifyResponse verifyResponse = SendSMSUtils.verifyOtp(requestId, code);
        //根据相应结果判断是否验证成功
        if (verifyResponse.getData().isMatch()) {
            //验证码正确
            if (!"".equals(filename)) {
                driver.setPic(filename);
            }
            if (!"".equals(licencePicFilename)) {
                driver.setLicencePic(licencePicFilename);
            }
            driverService.updateById(driver.setVerify(0));
            return ReturnMsg.success("申请提交成功，请耐心等待审核通过");
        } else {
            //验证失败
            if (verifyResponse.getData().getReasonType() == 2) {
                return ReturnMsg.fail("验证码错误");
            } else {
                return ReturnMsg.fail("验证码已过期或不存在");
            }
        }


    }

    /**
     * 处理司机接单操作和完成订单请求
     *
     * @param orderId  订单id
     * @param driverId 司机id
     * @param status   订单状态
     * @return 包装对象
     */
    @PutMapping("/driver/order/{id}")
    public ReturnMsg acceptOrder(@PathVariable("id") String orderId,
                                 @RequestParam("dId") Integer driverId,
                                 @RequestParam("status") Integer status) throws WxErrorException {
        Order order = orderService.getById(orderId);
        Driver driver = driverService.getById(driverId);
        Car car = carService.getById(order.getCarId());
        IService iService = new WxService();
        //得到客户信息
        Customer customer = customerService.getById(order.getCId());

        //设置模板消息
        Map<String, Object> firstData = new HashMap<>();
        Map<String, Object> orderIdData = new HashMap<>();
        Map<String, Object> statusData = new HashMap<>();
        Map<String, Object> dNameData = new HashMap<>();
        Map<String, Object> phoneData = new HashMap<>();
        Map<String, Object> licenceData = new HashMap<>();
        Map<String, Object> timeData = new HashMap<>();
        Map<String, Object> remarkData = new HashMap<>();
        firstData.put(WxTemplatesConst.VALUE, "您好，" + customer.getName());
        firstData.put(WxTemplatesConst.COLOR, WxTemplatesConst.BLACK);
        orderIdData.put(WxTemplatesConst.VALUE, orderId);
        orderIdData.put(WxTemplatesConst.COLOR, WxTemplatesConst.BLACK);
        dNameData.put(WxTemplatesConst.VALUE, driver.getName());
        dNameData.put(WxTemplatesConst.COLOR, WxTemplatesConst.BLACK);
        phoneData.put(WxTemplatesConst.VALUE, driver.getPhone());
        phoneData.put(WxTemplatesConst.COLOR, WxTemplatesConst.BLACK);
        licenceData.put(WxTemplatesConst.VALUE, car.getLicence());
        licenceData.put(WxTemplatesConst.COLOR, WxTemplatesConst.BLACK);
        timeData.put(WxTemplatesConst.VALUE, MyUtil.getTimeStr(order.getAppointmentTime()));
        timeData.put(WxTemplatesConst.COLOR, WxTemplatesConst.BLACK);
        remarkData.put(WxTemplatesConst.VALUE, order.getRemark());
        remarkData.put(WxTemplatesConst.COLOR, WxTemplatesConst.BLACK);

        //判断是接单还是完单
        if (status == 1) {
            //判断是否被其他司机接单
            if (order.getDId() != null) {
                return ReturnMsg.fail("该订单已被其他司机接受");
            }
            if (driver.getStatus() == 1) {
                return ReturnMsg.fail("您有进行中的订单，请完成后再接单");
            } else if (driver.getStatus() == 2) {
                return ReturnMsg.fail("您已被管理员禁用，不可接单");
            }

            //给订单设置司机和状态
            order.setDId(driverId).setStatus(status);
            orderService.updateById(order);
            //给司机设置状态
            driver.setStatus(1);
            //更新司机状态
            driverService.updateById(driver);

            //设置模板消息的状态数据
            statusData.put(WxTemplatesConst.VALUE, "已接单");
            statusData.put(WxTemplatesConst.COLOR, WxTemplatesConst.GREEN);
        } else if (status == 2) {
            //更新订单状态和完成时间
            order.setStatus(status).setCompletionTime(LocalDateTime.now());
            orderService.updateById(order);
            //更新司机状态和账户余额
            driver.setStatus(0).
                    setAccount(driver.getAccount().add(order.getPrice())).
                    setOrderNumber(driver.getOrderNumber() + 1);
            driverService.updateById(driver);
            //更新车辆状态
            carService.updateById(car.setStatus(0));

            //设置模板消息的状态数据
            statusData.put(WxTemplatesConst.VALUE, "已完成");
            statusData.put(WxTemplatesConst.COLOR, WxTemplatesConst.RED);
        }
        OrderStatusTemplateData ordersData = new OrderStatusTemplateData();
        ordersData.setFirst(firstData)
                .setOrderId(orderIdData)
                .setDName(dNameData)
                .setPhone(phoneData)
                .setLicence(licenceData)
                .setTime(timeData)
                .setRemark(remarkData)
                .setStatus(statusData);

        WxTemplate<OrderStatusTemplateData> orderStatusTemplate = new WxTemplate<>();
        orderStatusTemplate.setTouser(customer.getOpenId())
                .setTemplate_id(TEMPLATEID)
                .setTopcolor("#173117")
                .setData(ordersData)
                .setTopcolor(WxTemplatesConst.BLACK)
                .setUrl("http://50er112323.zicp.vip/wx/order_detail?id=" + orderId + "&status=" + status);

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
        url = url.replace("ACCESS_TOKEN", iService.getAccessToken());
        //发送模板消息
        HttpUtils.sendPost(url, JSON.toJSONString(orderStatusTemplate));
        if (status == 1) {
            return ReturnMsg.success("接单成功，请联系客户完成订单");
        } else if (status == 2) {
            return ReturnMsg.success("订单已完成");
        }
        return ReturnMsg.fail("操作失败");
    }


}
